package main

import (
	"context"
	"fmt"
	"github.com/gorilla/websocket"
	"github.com/pkg/errors"
	"golang.org/x/sync/errgroup"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
)

type httpHandler struct {
}

func (h *httpHandler) ServeHTTP(response http.ResponseWriter, r *http.Request) {

}

type wsHandler struct {
}

// websocket 连接处理函数
func (h *wsHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	upgrade := websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		// 允许所有的CORS 跨域请求，正式环境可以关闭
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
	// 应答客户端告知升级连接为websocket
	_, err := upgrade.Upgrade(resp, req, nil)
	if err != nil {
		// 取消
		return
	}
	// do something ....
}
func main() {
	ctx := context.Background()
	group, ctxNew := errgroup.WithContext(ctx)

	//	1. 监听8080端口 web服务
	web := &http.Server{Handler: &httpHandler{}, Addr: "0.0.0.0:8084"}
	group.Go(func() error {
		fmt.Println("开始监听 web 服务")
		err := web.ListenAndServe()
		return err
	})
	group.Go(func() error {
		defer fmt.Println("退出 WEB 服务")
		<-ctxNew.Done()
		return web.Close()
	})

	//	2. 监听8081端口 websocket服务
	ws := &http.Server{Handler: &wsHandler{}, Addr: "0.0.0.0:8083"}
	group.Go(func() error {
		fmt.Println("开始监听 ws 服务")
		err := ws.ListenAndServe()
		return err
	})
	group.Go(func() error {
		defer fmt.Println("退出 ws 服务")
		<-ctxNew.Done()
		return ws.Close()
	})

	//	3. 监听8082端口 pprof调试
	pf := &http.Server{Handler: nil, Addr: "0.0.0.0:8085"}
	group.Go(func() error {
		fmt.Println("开始监听 pprof 调试")
		err := pf.ListenAndServe()
		return err
	})
	group.Go(func() error {
		defer fmt.Println("退出 pprof 服务")
		<-ctxNew.Done()
		return pf.Close()
	})

	quit := make(chan os.Signal)
	// 等待系统退出进程
	group.Go(func() error {
		fmt.Println("开始监听进程退出信号")
		signal.Notify(quit, os.Interrupt, os.Kill)
		<-quit
		fmt.Println("收到进程退出信号")
		return errors.New("退出所有进程")
	})
	group.Go(func() error {
		<-ctxNew.Done()
		close(quit)
		return nil
	})

	err := group.Wait()
	fmt.Printf("%v\n", err)
}
